#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/mm.h>

/**
 * @brief 内核模块初始化函数
 * 
 * 模块加载时调用此函数，打印当前进程的虚拟内存区域信息。
 * 
 * @return int 成功返回0，未找到内存描述符返回-1
 */
static int __init print_vm_areas_init(void)
{
    struct task_struct *task = current; ///< 当前任务的task_struct
    struct mm_struct *mm = task->mm;    ///< 当前任务的内存描述符

    if (!mm) {
        printk(KERN_INFO "No memory descriptor found for current task.\n");
        return -1; ///< 如果没有内存描述符（可能是内核线程），返回错误
    }

    printk(KERN_INFO "Virtual memory areas for process: %s (PID: %d)\n", task->comm, task->pid);

    struct vm_area_struct *vma; ///< 虚拟内存区域结构体指针
    // 遍历所有虚拟内存区域
    for (vma = mm->mmap; vma; vma = vma->vm_next) {
        unsigned long start = vma->vm_start; ///< 虚拟内存区域起始地址
        unsigned long end = vma->vm_end;     ///< 虚拟内存区域结束地址
        unsigned long length = end - start;  ///< 虚拟内存区域长度

        printk(KERN_INFO "VMA Start: 0x%lx, Length: %lu bytes\n", start, length);
    }

    return 0; ///< 返回初始化成功
}

/**
 * @brief 内核模块清理函数
 * 
 * 模块卸载时调用此函数，打印退出日志信息。
 */
static void __exit print_vm_areas_exit(void)
{
    printk(KERN_INFO "VM areas module exited.\n"); ///< 打印模块卸载信息
}

module_init(print_vm_areas_init); ///< 指定模块初始化函数
module_exit(print_vm_areas_exit); ///< 指定模块退出函数

MODULE_LICENSE("GPL"); ///< 指定模块许可证为GPL
MODULE_DESCRIPTION("Print current process's virtual memory areas"); ///< 模块描述
MODULE_AUTHOR("Zhenxiong Chen"); ///< 模块作者
